/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xenon3d;

import java.util.logging.Logger;
import javax.media.opengl.GLProfile;
import javax.swing.JFrame;
import xenon3d.scene.DuplicateAttachmentException;

/**
 * The Xenon3D class implements a JFrame based 3D window which can be made
 * visible either in windowed or in full screen exclusive mode.
 * @author Volker Everts
 * @version 0.1 - 12.08.2011: Created
 */
public class Xenon3D {

    // <editor-fold defaultstate="collapsed" desc=" Constant Attributes ">

    /** Error message: "Canvas3D Already Attached". */
    static final String ERR_CANVAS_ALREADY_ATTACHED = "Canvas3D Already Attached";

    /** Error message: "View3D Already Attached". */
    static final String ERR_VIEW_ALREADY_ATTACHED = "View3D Already Attached";

    /** Error message: "Off-Screen Canvas3D Not Supported". */
    static final String ERR_OFFSCREEN_CANVAS = "Off-Screen Canvas3D Not Supported";

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Package Private Attributes ">

    /** The Xenon3D logger. */
    private static final Logger logger;

    /**
     * Returns the Xenon3D logger.
     * @return the logger singleton
     */
    Logger getLogger() {
        return logger;
    }

    /** The internal GLProfile. */
    private static GLProfile profile;

    /**
     * Returns the internal GLProfile object.
     * @return the GLProfile singleton
     */
    public static GLProfile getProfile() {
        return profile;
    }

    // static initializer
    static {
        GLProfile.initSingleton(true);
        profile = GLProfile.getDefault();
        logger = Logger.getLogger("Xenon3D");
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Private Fields ">

    /** The application title. */
    private String title;

    /** The internal JFrame object. */
    private JFrame frame;

    /** The attached Canvas3D object. */
    private Canvas3D canvas;

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Initialization ">

    /**
     * Creates a new Xenon3D object using default properties. The default
     * properties are:<p>
     * <li>Title: Xenon3D</li>
     * <li>WindowWidth: 640</li>
     * <li>WindowHeight: 480</li>
     * <li>WindowVisible: Yes</li>
     * </ul>
     */
    public Xenon3D() {
        this("Xenon3D", 640, 480, true);
    }

    /**
     * Creates a new Xenon3D object using the specified title and default
     * properties otherwise.
     * @param title the main window title
     */
    public Xenon3D(String title) {
        this(title, 640, 480, true);
    }

    /**
     * Creates a new Xenon3D object using the specified title, window size and
     * initial visibility.
     * @param title the initial window title
     * @param width the initial window width
     * @param height the initial window height
     * @param visible the initial window visibility
     */
    public Xenon3D(String title, int width, int height, boolean visible) {
        this(new JFrame(title));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(width, height);
        frame.setLocationByPlatform(true);
        frame.setVisible(visible);
    }

    /**
     * Creates a new Xenon3D object using the specified frame as the main 3D
     * window.
     * @param frame the frame to use as the main 3D window
     */
    public Xenon3D(JFrame frame) {
        this.frame = frame;
        title = frame.getTitle();
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Public Properties ">

    /**
     * Returns the application title.
     * @return the application title
     */
    public String getTitle() {
        return title;
    }

    /**
     * Sets the application title.
     * @param title the application title
     */
    public void setTitle(String title) {
        this.title = title;
        frame.setTitle(title);
    }

    /**
     * Returns the main 3d window as a JFrame object.
     * @return the JFrame window
     */
    public JFrame getJFrame() {
        return frame;
    }

    /**
     * Returns the currently attached Canvas3D object, or null, if no Canvas3D
     * is attached.
     * @return the attached Canvas3D
     */
    public synchronized Canvas3D getCanvas() {
        return canvas;
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" Public Mathods ">

    /**
     * Attaches the specified Canvas3D object to the main application window.
     * @param canvas the Canvas3D to attach
     */
    public synchronized void attachCanvas(Canvas3D canvas) {
        if (this.canvas != null) throw new DuplicateAttachmentException(ERR_CANVAS_ALREADY_ATTACHED);
        canvas.addNotify(frame);
        this.canvas = canvas;
    }

    /**
     * Removes any attached Canvas3D from the main application window.
     */
    public synchronized void removeCanvas() {
        if (canvas == null) return;
        canvas.removeNotify(frame);
        canvas = null;
    }

    // </editor-fold>

} // end class Xenon3D